<?php
// +-------------------------------------------------------------+
// | Tinysupe [ SIMPLE IS THE BEST ! ]
// +-------------------------------------------------------------+
// | Copyright (c) 2012 www.srccn.com All rights reserved.
// +-------------------------------------------------------------+
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +-------------------------------------------------------------+
// | Author: tinysu <tinysu@qq.com>
// +-------------------------------------------------------------+

/*****************************************************************
* Name:		SRCCN!Spider/1.1
* 
* Useage:	$ss = new sspider();
* 			$qs = $ss->query(array(
*				'http://site.srccn.com/spider.html',
*				'http://www.apache.org/licenses/LICENSE-2.0'
*			));
*			print_r($qs);
*
* Updated:	2012-01-30
******************************************************************/

class sspider{
	private $opts = array();
	private $spider = 'http://site.srccn.com/spider.html';
	private $uagent = 'Mozilla/5.0 (compatible; SRCCN!Spider/1.1; +http://site.srccn.com/spider.html)';
	
	public $multis = array();
	public $status, $header, $content;
	public $version = 'SRCCN!Spider/1.1';
	
	function __construct($opts=array()) {
		$this->opts = $opts;
		$this->opts[CURLOPT_TIMEOUT] = 30;
		$this->opts[CURLOPT_REFERER] = $this->spider;
		$this->opts[CURLOPT_USERAGENT] = $this->uagent;
		$this->opts[CURLOPT_RETURNTRANSFER] = 1;
		$this->opts[CURLOPT_FOLLOWLOCATION] = 1;
	}
	
	public function setopt($opt, $val=null) {
		$this->opts[$opt] = $val;
	}
	
	// compatible v1.0
	public function request($url) {
		return $this->query_url($url);
	}
	
	public function query($url) {
		if(!is_array($url)) return $this->query_url($url);
		return $this->query_mult($url);
	}
	
	public function query_url($url) {
		// curl_init
		$ch = curl_init();
		$this->status = 0;
		$this->header = '';
		$this->content = '';
		$this->opts[CURLOPT_URL] = $url;
		$this->opts[CURLOPT_HEADER] = 1;
		curl_setopt_array($ch, $this->opts);
		// curl_exec
		set_time_limit(35);
		$out = curl_exec($ch);
		if (curl_errno($ch)) return false;
		$this->status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		// curl_close
		curl_close($ch);
		
		// convert to utf-8
		@list($h, $c) = explode("\r\n\r\n", $out, 2);
		$c = $this->iconv_utf8($c, $h);
		$this->content = $c;
		$this->header = $h;
		
		return $c;
	}
	
	public function query_mult($url) {
		$this->status = 0;
		$this->header = '';
		$this->content = '';
		if(!is_array($url)) return false;
		
		// curl_multi_init
		$ac = null;
		$ch = array();
		$mh = curl_multi_init();
		$this->opts[CURLOPT_HEADER] = 1;
		foreach ($url as $k => $v) {
			$ch[$k] = curl_init();
			$this->opts[CURLOPT_URL] = $v;
			curl_setopt_array($ch[$k], $this->opts);
			curl_multi_add_handle($mh, $ch[$k]);
		}
		// curl_multi_exec
		do {
			$mc = curl_multi_exec($mh, $ac);
		} while ($mc == CURLM_CALL_MULTI_PERFORM);
		
		while ($ac && $mc == CURLM_OK) {
			set_time_limit(60);
			if (curl_multi_select($mh) != -1) {
				do {
					$mc = curl_multi_exec($mh, $ac);
				} while ($mc == CURLM_CALL_MULTI_PERFORM);
			}
		}
		//curl_multi_getcontent
		$ret = array();
		$this->multis = array();
		foreach ($ch as $k => $v) {
			$out = curl_multi_getcontent($v);
			@list($h, $c) = explode("\r\n\r\n", $out, 2);
			$c = $this->iconv_utf8($c, $h);
			$this->multis[$k] = array(
				'errno' => curl_errno($v),
				'status' => curl_getinfo($v, CURLINFO_HTTP_CODE),
				'header' => $h,
				'content' => $c
			);
			$ret[$k] = $c;
		}
		// curl_multi_close
		foreach ($ch as $v) {
			$out = curl_multi_remove_handle($mh, $v);
		}
		curl_multi_close($mh);
		
		return $ret;
	}
	
	private function iconv_utf8($c, $h=null) {
		// charset array
		$a = array(
			'UTF-8', 'GB2312', 'GBK', 'BIG5', 'ASCII', 'EUC-JP',
			'Shift_JIS', 'CP936', 'ISO-8859-1', 'JIS', 'eucjp-win', 'sjis-win'
		);
		// detect content
		if (!($e = mb_detect_encoding($c, $a))) {
			// match content
			preg_match('/<meta.+?charset=[^\w]?([-\w]+)/i', $c, $m);
			if (!isset($m[1])) {
				// match header
				is_null($h) or preg_match('/charset=[^\w]?([-\w]+)/is', $h, $m);
			}
			if (isset($m[1])) $e = $m[1];
		}

		// get charset
		$t = $e ? strtolower($e) : false;
		// convert to utf-8
		if ($t!='utf-8' && $t!==false) {
			$c = mb_convert_encoding($c, 'utf-8', $t);
		}

		return $c;
	}
	
	function __destruct() {
		
	}
}
?>